﻿#region Copyright Notices
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Library General Public License for more details.
// 
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Yarr.YarrPad
{
    /// <summary>
    /// Interaction logic for Console.xaml
    /// </summary>
    public partial class CmdConsole : Window, IDebuggerBreak, IProfiler
    {
        public CmdConsole()
        {
            InitializeComponent();
            Runtime.Profiler = this;
            Runtime.AttachDebugger(this);
        }

        private void YarrPad_Loaded(object sender, RoutedEventArgs e)
        {
            console.console.Focus();
        }


        #region IDebuggerBreak Implementation

        /// <summary>
        /// Invoked by the debugger when a breakpoint is encountered
        /// </summary>
        /// <param name="debugger">The debugger instance</param>
        /// <param name="currentFrame">The current stack frame</param>
        /// <returns>The object returned replaces the actual object being evaluated</returns>
        public Object DebugBreak(IDebugger debugger, StackFrame currentFrame)
        {
            if (currentFrame.Form is Yarr.Cons)
            {
                DbgConsole debug = new DbgConsole();
                debug.InitDebugger(debugger, currentFrame);
                debug.ShowDialog();
            }

            return currentFrame.Form;
        }

        /// <summary>
        /// Called when a debug message is encountered
        /// </summary>
        /// <param name="debugger">The debugger instance</param>
        /// <param name="comment">The comment to be printed</param>
        /// <param name="env">the current execution environment</param>
        public void DebugPrint(IDebugger debugger, string comment, Environment env)
        {
            console.console.WriteLine(String.Empty, TextType.DebugOut);
            console.console.Write(comment, TextType.DebugOut);
        }

        /// <summary>
        /// Called when a stack frame with a breakpoint is being exited
        /// </summary>
        /// <param name="debugger">The debugger instance</param>
        /// <param name="value">The value being returned</param>
        /// <param name="currentFrame">The stack frame being exited</param>
        /// <returns>The value returned replaces the actual value that was evaluated</returns>
        public Object ReturnValue(IDebugger debugger, StackFrame currentFrame, Object value)
        {
            if (currentFrame.Form is Yarr.Cons)
            {
                string title = currentFrame.Form.ToString();
                if (title.Length > 40)
                    title = title.Substring(0, 35) + " ...";

                string result = Printer.WriteToString(value);

                InputDlg returnDlg = new InputDlg(title, "Returning:");
                returnDlg.inputBox.Text = result;

                bool? dlgOk = returnDlg.ShowDialog();
                if (dlgOk.HasValue && dlgOk.Value && returnDlg.InputText != result)
                    value = Runtime.EvalString(returnDlg.InputText, currentFrame.ExecutionEnvironment);
            }

            console.console.WriteOutput();

            return value;
        }
        #endregion

        #region IProfiler Implementation
        void IProfiler.Open() { }

        object IProfiler.TraceCall(object form, Environment env) { return form; }

        object IProfiler.TraceReturn(object form, Environment env) 
        {
            console.console.WriteOutput();
            return form;
        }

        void IProfiler.Comment(string str, Environment env)
        {
            console.console.WriteLine(String.Empty, TextType.DebugOut);
            console.console.Write(str, TextType.DebugOut);
        }

        void IProfiler.Close() { }
        #endregion

        private void YarrPad_LocationChanged(object sender, EventArgs e)
        {
            console.console.SizeOrLocationChanged();
        }

        private void YarrPad_SizeChanged(object sender, SizeChangedEventArgs e)
        {
           console.console.SizeOrLocationChanged();
        }
    }
}
